package top.maof.mfcoin.algo;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.*;

/**
 * 密码学工具类
 *
 * @author 毛逢
 * @date 2021/5/24 15:36
 */
public class SecretUtil {

    public static final String DIGEST_ALGORITHM_MD5 = "md5";
    // "SHA1", "SHA-256", "SHA-384", "SHA-512"
    public static final String DIGEST_ALGORITHM_SHA256 = "SHA-256";


    public static final String DIGEST_ALGORITHM_SHA1 = "SHA1";
    public static final String DIGEST_ALGORITHM_SHA384 = "SHA-384";
    public static final String DIGEST_ALGORITHM_SHA512 = "SHA-512";

    // 签名算法
    public static final String SIGN_ALGORITHM_MD5 = "MD5withRSA";


    // 防止在不同的计算机上的默认字符编码不一致,全部采用utf-8
    private static final String CHARSET = "utf-8";

    // 对称加密 DES 算法 加密密钥  8个字节
    private static final String DES_KEY = "MAO-FENG";

    // 对称加密 AES 算法 加密密钥 16个字节
    private static final String AES_KEY = "MAO-FENGMAO-FENG";


    /**
     * 数字摘要算法/哈希算法,包括 md5/sha1/sha256等
     *
     * @param: [algorithm, msg]
     * @return: byte[]
     * @author 毛逢
     */
    public static byte[] digest(String algorithm, String msg) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        MessageDigest md5 = MessageDigest.getInstance(algorithm);
        md5.update(msg.getBytes(CHARSET));
        return md5.digest();
    }

    /**
     * 数字摘要算法/哈希算法,包括 md5/sha1/sha256等
     *
     * @param: [algorithm, msg]
     * @return: byte[]
     * @author 毛逢
     */
    public static byte[] digest(String algorithm, byte[] msg) throws NoSuchAlgorithmException {
        MessageDigest md5 = MessageDigest.getInstance(algorithm);
        md5.update(msg);
        return md5.digest();
    }

    /**
     * DES 加密
     *
     * @param: [msg 需要加密的字符串]
     * @return: byte[]
     * @author 毛逢
     * @eamil 3286408344@qq.com
     * @date: 2021/6/2 9:30
     */
    public static byte[] desEncrypt(String msg) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {
        Cipher cipher = Cipher.getInstance("DES");
        SecretKey desKey = new SecretKeySpec(DES_KEY.getBytes(), "DES");
        cipher.init(Cipher.ENCRYPT_MODE, desKey);
        return cipher.doFinal(msg.getBytes(CHARSET));
    }

    /**
     * DES 解密
     *
     * @param: [bytes DES加密后得到的字节数组]
     * @return: java.lang.String
     * @author 毛逢
     * @eamil 3286408344@qq.com
     * @date: 2021/6/2 9:31
     */
    public static String desDecrypt(byte[] bytes) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {
        Cipher cipher = Cipher.getInstance("DES");
        SecretKey desKey = new SecretKeySpec(DES_KEY.getBytes(), "DES");
        cipher.init(Cipher.DECRYPT_MODE, desKey);
        return new String(cipher.doFinal(bytes), CHARSET);
    }

    /**
     * AES 加密
     *
     * @param: [msg 需要加密的字符串]
     * @return: byte[]
     * @author 毛逢
     * @eamil 3286408344@qq.com
     * @date: 2021/6/2 9:30
     */
    public static byte[] aesEncrypt(String msg) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {
        Cipher cipher = Cipher.getInstance("AES");
        SecretKey desKey = new SecretKeySpec(AES_KEY.getBytes(), "AES");
        cipher.init(Cipher.ENCRYPT_MODE, desKey);
        return cipher.doFinal(msg.getBytes(CHARSET));
    }

    /**
     * AES 解密
     *
     * @param: [bytes AES加密后得到的字节数组]
     * @return: java.lang.String
     * @author 毛逢
     * @eamil 3286408344@qq.com
     * @date: 2021/6/2 9:31
     */
    public static String aesDecrypt(byte[] bytes) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {
        Cipher cipher = Cipher.getInstance("AES");
        SecretKey desKey = new SecretKeySpec(AES_KEY.getBytes(), "AES");
        cipher.init(Cipher.DECRYPT_MODE, desKey);
        return new String(cipher.doFinal(bytes), CHARSET);
    }

    /**
     * 签名
     *
     * @param: [privateKey, msg]
     * @return: byte[]
     * @author 毛逢
     * @eamil 3286408344@qq.com
     * @date: 2021/6/2 11:00
     */
    public static byte[] sign(PrivateKey privateKey, byte[] msg) throws Exception {
        Signature signature = Signature.getInstance(privateKey.getAlgorithm());
        signature.initSign(privateKey);
        signature.update(msg);
        return signature.sign();
    }

    /**
     * 验证签名
     *
     * @param: [publicKey, msg, signatureByte]
     * @return: boolean
     * @author 毛逢
     * @eamil 3286408344@qq.com
     * @date: 2021/6/2 11:00
     */
    public static boolean verify(PublicKey publicKey, byte[] msg, byte[] signatureByte) {
        Signature signature = null;
        try {
            signature = Signature.getInstance(publicKey.getAlgorithm());
            signature.initVerify(publicKey);
            signature.update(msg);
            return signature.verify(signatureByte);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

}
